home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 24 / CU Amiga Magazine's Super CD-ROM 24 (1998)(EMAP Images)(GB)(Track 1 of 2)[!][issue 1998-07].iso / CUCD / Programming / SWI / source / man / runtime.doc (.txt) < prev    next >
Encoding:
LaTeX Document  |  1998-02-04  |  15.5 KB  |  346 lines

  1. \chapter{Generating Runtime Applications}    \label{sec:runtime}
  2. This chapter describes the features of SWI-Prolog for delivering
  3. applications that can run without the development version of the
  4. system installed.
  5. A SWI-Prolog built application consists of at least two parts: the
  6. emulator and the compiled application. The latter is in the same format
  7. as a SWI-Prolog boot-file and SWI-Prolog pre-compiled (QLF) file. This
  8. format is fast loadable and abstracted just far enough to be machine
  9. independent. This implies an application delivered in binary format
  10. can run on any computer for which an emulator is available without
  11. modification.
  12. \begin{description}
  13.     \predicate{qsave_program}{2}{+File, +ListOfOptions}
  14. Saves the current state of the program to the file \arg{File}. The
  15. result is an executable shell-script, that will start the emulator.
  16. \arg{ListOfOptions} is a list of $<Key> = <Value>$ or $<Key>(<Value>)$
  17. pairs. The available keys are described in \tabref{qsave-options}.
  18. \begin{table}
  19. \begin{center}
  20. \begin{tabular}{|l|c|c|l|}
  21. \hline
  22. \bf Key & \bf Option    & \bf Type      & \bf Description \\
  23. \hline
  24. local    & \bf -L       & K-bytes       & Size (Limit) of local stack \\
  25. global   & \bf -G       & K-bytes       & Size (Limit) of global stack \\
  26. trail    & \bf -T       & K-bytes       & Size (Limit) of trail stack \\
  27. argument & \bf -A       & K-bytes       & Size (Limit) of argument stack \\
  28. goal     & \bf -g       & atom          & Initialisation goal \\
  29. toplevel & \bf -t       & atom          & Prolog toplevel goal \\
  30. init_file& \bf -f       & atom          & Personal initialisation file \\
  31. \hline
  32. autoload &              & bool          & If true, run autoload/0 first \\
  33. map      &              & atom          & File containing info on dump \\
  34. op       &              & \tt save/standard & Save operator declarations? \\
  35. stand_alone &           & bool          & Include the emulator in the state \\
  36. \hline
  37. \end{tabular}
  38. \end{center}
  39.     \caption{<Key> = <Value> pairs for qsave_program/2}
  40.     \label{tab:qsave-options}
  41. \end{table}
  42. The \program{/bin/sh} script contains the following data:
  43. \begin{enumerate}
  44.     \item The \jargon{shell script header} starts as:
  45. \begin{code}
  46. #!/bin/sh
  47. #SAVE-VERSION=<num>
  48. #PROLOG-VERSION=<num>
  49. exec ${SWIPL-/path-to-emulator} -x $0 "$@"
  50. \end{code}
  51.     \item The \jargon{settings section} contains the default values
  52.           for the various command line options.
  53.     \item The \jargon{predicates section} contains all predicates from
  54.           the currently running system. Clauses of predicates defined as
  55.           \jargon{volatile} (see volatile/1) are \strong{not} saved.  Neither
  56.           are foreign predicates (see also below).
  57.     \item The \jargon{record section} contains the database records saved
  58.           with recorda/3 and friends.  The current version saves records
  59.           using directives.
  60.     \item The \jargon{flag section} contains the global flags saved using
  61.           the flag/3 predicate.  Flags are saved as directives.
  62.     \item The \jargon{feature section} contains all features that do not
  63.           originate from the emulator itself.  See set_feature/2.
  64.     \item The \jargon{import section} contains the imports as far as they
  65.           are not handled by the auto-import system.  That is, an import
  66.           is stored if the module is \const{user} or the module
  67.       \const{user} contains a different definition as the one
  68.       imported in the target module.'
  69. \end{enumerate}
  70. Before writing the data to file, qsave_program/2 will run autoload/0 to
  71. all required autoloading the system can discover.  See autoload/0.
  72. Provided the application does not require any of the Prolog libraries to
  73. be loaded at runtime, the only file from the SWI-Prolog development
  74. environment required is the emulator itself.  The emulator may be built
  75. in two flavours.  The default is the \jargon{development emulator}.  The 
  76. \jargon{runtime emulator} is similar, but lacks the tracer. The stand-alone
  77. program \manref{chpl}{1} may be used to change the default path
  78. to the emulator.
  79. If the option \exam{stand_alone(on)} is present, the emulator is
  80. prepended for the state. If the emulator is started and no state is
  81. specified using the \cmdlineoption{-x}{} flag, it will test whether a
  82. boot-file (state) is attached to the emulator itself and load this
  83. state. Provided the application has all libraries loaded, the resulting
  84. file may be started anywhere.
  85.     \predicate{qsave_program}{1}{+File}
  86. Equivalent to \exam{qsave_program(File, [])}.
  87.     \predicate{autoload}{0}{}
  88. Check the current Prolog program for predicates that are referred to, 
  89. are undefined and have a definition in the Prolog library.  Load the
  90. appropriate libraries.
  91. This predicate is used by qsave_program/[1,2] to ensure the saved state
  92. will not depend on one of the libraries. The predicate autoload/0 will
  93. find all \strong{direct} references to predicates. It does not find
  94. predicates referenced via meta-predicates. The predicate {log}/2 is
  95. defined in the library(quintus) to provide a quintus compatible means to
  96. compute the natural logarithm of a number. The following program will
  97. behave correctly if its state is executed in an environment where the
  98. library(quintus) is not available:
  99. \begin{code}
  100. logtable(From, To) :-
  101.         From > To, !.
  102. logtable(From, To) :-
  103.         log(From, Value),
  104.         format('~d~t~8|~2f~n', [From, Value]),
  105.         F is From + 1,
  106.         logtable(F, To).
  107. \end{code}
  108. However, the following implementation refers to {log}/2 through the
  109. meta-predicate maplist/3.  Autoload will not be able to find the
  110. reference.  This problem may be fixed either by loading the
  111. module libtary(quintus) explicitly or use require/1 to tell the
  112. system that the predicate {log}/2 is required by this module.
  113. \begin{code}
  114. logtable(From, To) :-
  115.         findall(X, between(From, To, X), Xlist),
  116.         maplist(log, Xlist, SineList),
  117.         write_table(Xlist, SineList).
  118. write_table([], []).
  119. write_table([I|IT], [V|VT]) :-
  120.         format('~d~t~8|~2f~n', [I, V]),
  121.         write_table(IT, VT).
  122. \end{code}
  123.     \prefixop{volatile}{+Name/Arity, \ldots}
  124. Declare that the clauses of specified predicates should \strong{not} be
  125. saved to the program.  The volatile declaration is normally used to
  126. avoid that the clauses of dynamic predicates that represent data for
  127. the current session is saved in the state file.
  128. \end{description}
  129. \section{Limitations of qsave_program}
  130. There are three areas that require special attention when using
  131. qsave_program/[1,2].
  132. \begin{itemize}
  133.     \item
  134. If the program is an embedded Prolog application or uses the foreign
  135. language interface, care has to be taken to restore the appropriate
  136. foreign context. See \secref{qforeign} for details.
  137.     \item
  138. If the program uses directives (\exam{:- goal.} lines) that perform
  139. other actions then setting predicate attributes (dynamic, volatile,
  140. etc.) or loading files (consult, etc.), the directive may need to be
  141. prefixed with initialization/1.
  142.     \item
  143. `Database references as returned by clause/3, recorded/3, etc.
  144. are not preserved and may thus not be part of the database when saved.
  145. \end{itemize}
  146. \section{Runtimes and Foreign Code}
  147. \label{sec:qforeign}
  148. Some applications may need to use the foreign language interface.
  149. Object code is by definition machine-dependent and thus cannot be
  150. part of the saved program file.
  151. To complicate the matter even further there are various ways of
  152. loading foreign code:
  153. \begin{itemlist}
  154.     \item [Using the library(shlib) predicates]
  155. This is the preferred way of dealing with foreign code. It loads quickly
  156. and ensures an acceptable level of independence between the versions of
  157. the emulator and the foreign code loaded.  It works on Unix machines
  158. supporting shared libraries and library functions to load them.  Most
  159. modern Unixes satisfy this constraint.%
  160.     \footnote{Linux with the old a.out format does \strong{not}}.
  161. It also works on the Win32 platform: Windows-NT, '95 and Windows 3.1
  162. running win32s.
  163.     \item [Static linking]
  164. This mechanism works on all machines, but generally requires the same
  165. C-compiler and linker to be used for the external code as is used to
  166. build SWI-Prolog itself.  This mechanism is the preferred way if shared
  167. libraries are not supported.
  168.     \item [Using {load_foreign/[2,5]}]
  169. Basically only works on Unix system supporting the a.out format
  170. executables.  This mechanism is slow and non-portable.  It should be
  171. avoided whenever possible.
  172. \end{itemlist}
  173. To make a runtime executable that can run on multiple platforms one
  174. must make runtime checks to find the correct way of linking.  Suppose
  175. we have a source-file {\tt myextension} defining the installation
  176. function \funcref{install}{}.
  177. If this file is compiled to a shared library, load_foreign_library/1
  178. will load this library and call the installation function to initialise
  179. the foreign code. If it is loaded as a static extension, define
  180. \funcref{install}{} as the predicate install/0:
  181. \begin{code}
  182. static foreign_t
  183. pl_install()
  184. { install();
  185.   PL_succeed;
  186. PL_extension PL_extensions [] =
  187. /*{ "name",     arity,  function,       PL_FA_<flags> },*/
  188.   { "install",  0,      pl_install,     0 },
  189.   { NULL,       0,      NULL,           0 }     /* terminating line */
  190. \end{code}
  191. Now, use the following Prolog code to load the foreign library:
  192. \begin{code}
  193. load_foreign_extensions :-
  194.         current_predicate(install, install), !, % static loaded
  195.         install.
  196. load_foreign_extensions :-                      % shared library
  197.         load_foreign_library(foreign(myextension)).
  198. :- initialization load_foreign_extensions.
  199. \end{code}
  200. The path alias \const{foreign} is defined by file_search_path/2.  By
  201. default it searches the directories \file{<home>/lib/<arch>} and
  202. \file{<home>/lib}.  The application can specify additional rules for
  203. file_search_path/2.
  204. \section{Finding Application files}
  205. If your application uses files that are not part of the saved program
  206. such as database files, configuration files, etc., the runtime version
  207. has to be able to locate these files. The file_search_path/2 mechanism
  208. in combination with the \cmdlineoption{-p}{alias} command-line argument
  209. is the preferred way to locate runtime files. The first step is to
  210. define an alias for the toplevel directory of your application. We will
  211. call this directory \file{gnatdir} in our examples.
  212. A good place for storing data associated with SWI-Prolog runtime systems
  213. is below the emulator's home-directory.  \const{swi} is a predefined alias
  214. for this directory.  The following is a useful default definition for
  215. the search path.
  216. \begin{code}
  217. user:file_search_path(gnatdir, swi(gnat)).
  218. \end{code}
  219. The application should locate all files using absolute_file_name.
  220. Suppose gnatdir contains a file {\tt config.pl} to define local
  221. configuration.  Then use the code below to load this file:
  222. \begin{code}
  223. configure_gnat :-
  224.         (   absolute_file_name(gnatdir('config.pl'), ConfigFile)
  225.         ->  consult(ConfigFile)
  226.         ;   format(user_error, 'gnat: Cannot locate config.pl~n'),
  227.             halt(1)
  228.         ).
  229. \end{code}
  230. \section{Using chpl for Configuration Information}
  231. \subsection{Changing the emulator of a runtime application}
  232. The program chpl, may be used to manipulate the header of a SWI-Prolog
  233. bootfile or state created with qsave_program/[1,2].
  234. It will be used most commonly by the installer of a SWI-Prolog runtime
  235. application to specify the path to the emulator. If the end-user decided
  236. to install the SWI-Prolog runtime environment in
  237. \begin{code}
  238. /usr/local/lib/rt-pl-2.1.4
  239. \end{code}
  240. the gnat application can be told to use this emulator using:
  241. \begin{code}
  242. % /usr/local/lib/rtpl-2.1.4/bin/chpl -e /usr/local/lib/rt-pl-2.1.4/bin/pl gnat
  243. \end{code}
  244. Now, {\tt gnat} may be installed in any public or private directory for
  245. binaries.
  246. \subsection{Passing a path to the application}
  247. Suppose the system administrator has installed the SWI-Prolog runtime
  248. environment in \file{/usr/local/lib/rt-pl-2.1.4}. A user wants to
  249. install \file{gnat}, but gnat will look for its configuration in
  250. \file{/usr/local/lib/rt-pl-2.1.4/gnat} where the user cannot write.
  251. The user decides to install the gnat runtime files in
  252. \file{/users/bob/lib/gnat}.  For one-time usage, the user may decide
  253. to start gnat using the command:
  254. \begin{code}
  255. % gnat -p gnatdir=/users/bob/lib/gnat
  256. \end{code}
  257. For a more widely used executable, this is not very comfortable.  The
  258. user may decide to edit the shell-script part of gnat.  Upto the line
  259. holding
  260. \begin{code}
  261. # End Header
  262. \end{code}
  263. gnat is a simple \program{/bin/sh} script.  After this line, the file is
  264. binary and may contain long lines.  Most editors are not capable of
  265. editing such files.%
  266.     \footnote{If you use GNU-Emacs, make sure \const{require-final-newline}
  267.           is set to \const{nil}}
  268. Instead of editing the file directly, the program \manref{chpl}{1} may be
  269. used to extract and replace the header of \file{gnat}.  The following
  270. editing sequence will work with any editor capable of editing ASCII
  271. files.
  272. \begin{code}
  273. % chpl -x gnat > gnat.hdr
  274. % emacs gnat.hdr
  275. % chpl -h gnat.hdr gnat
  276. \end{code}
  277. The header may be changed to the following to install gnat properly:
  278. \begin{code}
  279. #!/bin/sh
  280. # SWI-Prolog version: 2.1.4
  281. # SWI-Prolog save-version: 25
  282. exec ${SWIPL-/usr/local/lib/rt-pl-2.1.4/bin/pl} -x $0 \
  283.      -p gnatdir=/users/bob/lib/gnat "$@"
  284. \end{code}
  285. \section{The Runtime Environment}
  286. \subsection{The Runtime Emulator}
  287. The sources may be used to built two versions of the emulator. By
  288. default, the \jargon{development emulator} is built. This emulator
  289. contains all features for interactive development of Prolog
  290. applications. If the system is configured using
  291. \cmdlineoption{--enable-runtime}{}, \manref{make}{1} will create a
  292. \jargon{runtime version} of the emulator. This emulator is equivalent to
  293. the development version, except for the following features:
  294. \begin{itemlist}
  295.     \item [No input editing]
  296. The GNU library \clib{-lreadline} that provides EMACS compatible editing
  297. of input lines will not be linked to the system.
  298.     \item [No tracer]
  299. The tracer and all its options are removed, making the system a little
  300. faster too.
  301.     \item [No profiler]
  302. profile/3 and friends are not supported.  This saves some space and
  303. provides better performance.
  304.     \item [No interrupt]
  305. Keyboard interrupt (Control-C normally) is not rebound and will normally
  306. terminate the application.
  307.     \item [feature(runtime, true) succeeds]
  308. This may be used to verify your application is running in the runtime
  309. environment rather than the development environment.
  310.     \item [clause/[2,3] do not work on static predicates]
  311. This feature inhibits listing your program.  It is only a very limited
  312. protection however.
  313. \end{itemlist}
  314. The following fragment is an example for building the runtime
  315. environment in \file{\env{HOME}/lib/rt-pl-2.1.4}. If possible, the
  316. shared-library interface should be configured to ensure it can serve a
  317. large number of applications.
  318. \begin{code}
  319. % cd pl-2.1.4
  320. % mkdir runtime
  321. % cd runtime
  322. % ../src/configure --enable-runtime --prefix=$HOME
  323. % make
  324. % make rt-install
  325. \end{code}
  326. The runtime directory contains the components listed below. This
  327. directory may be tar'ed and shipped with your application.
  328. \begin{center}
  329. \begin{tabular}{|l|l|}
  330. \hline
  331. \file{README.RT}        & Info on the runtime environment \\
  332. \hline
  333. \file{bin/pl}           & The emulator itself \\
  334. \file{bin/chpl}         & The utility to change the runtime \\
  335. \hline
  336. \file{man/chpl.1}       & Manual page for chpl \\
  337. \file{man/pl.1}         & Manual page for pl \\
  338. \hline
  339. \file{swipl}            & pointer to the home directory (.) \\
  340. \hline
  341. \file{lib/}             & directory for shared libraries \\
  342. \file{lib/<arch>/}     & machine-specific shared libraries \\
  343. \hline
  344. \end{tabular}
  345. \end{center}
  346.